package BLC

import (
	"../wallet"
	"flag"
	"fmt"
	"github.com/gpmgo/gopm/modules/log"
	"os"
)

type CLI struct {

}

//bc *BlockChain
func NewCLI() *CLI {
	return &CLI{}
}

func (cli *CLI)CreateWallet(){
	wallets,_:=wallet.NewWallets()
	wallets.CreateNewWallet()
}

//打印参数,打印要求的参数
func (cli *CLI) PrintUsage() {
	fmt.Println("Usage:")
	fmt.Println("createwallet <创建钱包>")
	fmt.Println("getaddresslist <获取钱包地址的列表>")
	fmt.Println("getbalance -address ADDRESS <获得这个地址的余额>")
	fmt.Println("createblockchain -address ADDRESS <创建区块链并且把创世区块的东西奖励给挖矿地址")
	fmt.Println("printchain <打印整个区块链的内容>")
	fmt.Println("send -from FROM -to TO -amount AMOUNT <从from发送amount个代币给to>")
}

////打印整个区块链
func (cli *CLI) PrintBlockChain() {
	blockchain:=BlockChainObject()

	blockchain.ViewBlockChain()
}

func (cli *CLI)GetAddressList(){
	wallets,_:=wallet.NewWallets()
	for address,_:=range wallets.WalletsMap{
		fmt.Println(address)
	}
}

//验证参数的多少，避免数组越界问题
func (cli *CLI) ValidateAges() {
	if len(os.Args) < 2 {
		cli.PrintUsage()
		os.Exit(1)
	}
}

func (cli *CLI) Run() {
	cli.ValidateAges()
	getaddresslist:=flag.NewFlagSet("getaddresslist",flag.ExitOnError)
	createblockchain := flag.NewFlagSet("createblockchain", flag.ExitOnError)
	printBlock := flag.NewFlagSet("printchain", flag.ExitOnError)
	getbalance := flag.NewFlagSet("getbalance", flag.ExitOnError)
	send := flag.NewFlagSet("send", flag.ExitOnError)
	createwallet:=flag.NewFlagSet("createwallet",flag.ExitOnError)

	ginsitAddr := createblockchain.String("address", "", "这个是为了创建区块并且奖励给address地址")
	balanceAddr := getbalance.String("address", "", "这个是获取这个地址的余额")
	sendFrom := send.String("from", "", "这个是获取发送方的地址")
	sendTo := send.String("to", "", "这个是获取收取方的地址")
	sendAmount := send.Int("amount", 0, "这个是获取发送的总金额")

	switch os.Args[1] {
	case "createblockchain":

		err := createblockchain.Parse(os.Args[2:])
		if err != nil {
			panic(err)
		}

		if wallet.IsValidateAddress([]byte(*ginsitAddr))==false{
			log.Fatal("地址不正确!")
			os.Exit(1)
		}

		CreateGenistBlockChain(*ginsitAddr)
		fmt.Println("区块链创建成功!!!")
	case "printchain":

		err := printBlock.Parse(os.Args[2:])
		if err != nil {
			fmt.Printf("%v\n", err)
		}

		fmt.Println("正在打印区块链的信息......")
		cli.PrintBlockChain()
	case "send":

		err := send.Parse(os.Args[2:])
		if err != nil {
			fmt.Println("%v\n", err)
		}

		if !wallet.IsValidateAddress([]byte(*sendFrom)) || !wallet.IsValidateAddress([]byte(*sendTo)){
			log.Fatal("地址不正确!")
			os.Exit(1)
		}

		cli.send(*sendFrom,*sendTo,*sendAmount)

	case "getbalance":

		err := getbalance.Parse(os.Args[2:])
		if err != nil {
			fmt.Println("%v\n", err)
		}

		if wallet.IsValidateAddress([]byte(*balanceAddr))==false{
			log.Fatal("地址不正确!")
			os.Exit(1)
		}

		fmt.Println("你的余额为:",GetBalance(*balanceAddr))
	case "createwallet":

		err:=createwallet.Parse(os.Args[2:])
		if err!=nil{
			fmt.Println("%v\n",err)
		}

	case "getaddresslist":

		err:=getaddresslist.Parse(os.Args[2:])
		if err!=nil{
			fmt.Println("获取钱包地址列表失败!")
		}

	default:

		cli.PrintUsage()

		fmt.Printf("请正确输入参数和命令！")
	}

	if createblockchain.Parsed() {
		if *ginsitAddr == "" {
			fmt.Printf("你没有输入地址进来!\n")
			createblockchain.Usage()
			os.Exit(1)
		} else {
			//cli.AddBlock(*data)
		}
	}

	if createwallet.Parsed(){
		cli.CreateWallet()
	}

	if getaddresslist.Parsed(){
		cli.GetAddressList()
	}

	if send.Parsed() {
		if *sendFrom == "" || *sendTo == "" || *sendAmount == 0 {
			fmt.Println("你的发送的参数填写有误")
			send.Usage()
			os.Exit(1)
		} else {
			fmt.Printf("from:%s,to:%s,amount:%d\n", *sendFrom, *sendTo, *sendAmount)
		}
	}

	if getbalance.Parsed() {
		if *balanceAddr == "" {
			fmt.Println("你的填写的东西有错误")
			getbalance.Usage()
			os.Exit(1)
		} else {
			fmt.Printf("balanceAddr:%s\n", *balanceAddr)
		}
	}
}
